{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 一：KNN算法概述：\n",
    "\n",
    "KNN算法又称之为K-最近邻算法。它是一种基本分类算法。其原理大致如下：\n",
    "即一个样本在某个特征空间中有k个最近邻的样本，而这些中大多数样本属于同一类别，则该样本所属类别应与该类别一致。同时，该样本具有这个类别的样本特征。\n",
    "如此该算法在确定分类的决策上只通过最近邻的k个样本的类别来决定待分类样本的所属类别。\n",
    "\n",
    "对KNN算法的思想总结一下：就是在训练集中数据和标签已知的情况下，输入测试数据，将测试数据的特征与训练集中对应的特征进行相互比较，找到训练集中与之最为相似的前K个数据，则该测试数据对应的类别就是K个数据中出现次数最多的那个分类，其算法的描述为：\n",
    "\n",
    "1）计算测试数据与各个训练数据之间的距离；\n",
    "\n",
    "2）按照距离的递增关系进行排序；\n",
    "\n",
    "3）选取距离最小的K个点；\n",
    "\n",
    "4）确定前K个点所在类别的出现频率；\n",
    "\n",
    "5）返回前K个点中出现频率最高的类别作为测试数据的预测分类。\n",
    "\n",
    "### 二：KNN算法三要素：\n",
    "\n",
    "从上述算法概述可以看出，其原理很简单。如此，KNN的实现过程同样也简单。\n",
    "KNN算法的实现过程有三要素：k值的选择、样本间距离度量、决策（即用什么规则来确定）。首先我会从距离度量开始介绍：\n",
    "\n",
    "  1. ##### 样本间距离度量：\n",
    "\n",
    "   knn模型的特征空间一般是n维实数向量空间。而特征空间中两点间的距离可以看做是两个样本相似度的度量，反映为在空间上与集群距离的接近程度。进一步说，特征空间中两点间的距离又称之为向量的距离。\n",
    "   对于两个n维向量A(X1,X2,…,Xn)和B(Y1,Y2,…,Yn)。常用的距离有闵可夫斯基距离（里边又包含其他的距离）、欧氏距离、曼哈顿距离、切比雪夫距离、余弦距离。\n",
    "\n",
    "- **闵可夫斯基距离**：是一种通用距离，通过设定参数l的值来得到相应距离：\n",
    "  ![在这里插入图片描述](https://img-blog.csdnimg.cn/20190225032016219.jpg)\n",
    "  而l=1时，则是曼哈顿距离：差的绝对值之和\n",
    "  而l=2时，则是欧氏距离，在二维空间上表现为勾股定理的距离（默认距离）\n",
    "\n",
    "- **曼哈顿距离**：又称为城市距离，是两个向量间各对应点差的绝对值之和：\n",
    "  ![在这里插入图片描述](https://img-blog.csdnimg.cn/20190225032032303.jpg)\n",
    "\n",
    "- **欧式距离**：即两个向量间的空间距离，在二维平面上表现为勾股定理如：\n",
    "  ![在这里插入图片描述](https://img-blog.csdnimg.cn/20190225032152646.jpg)\n",
    "  在矩阵运算上表现为矩阵差与其差的转置乘积的开平方，即：\n",
    "  ![在这里插入图片描述](https://img-blog.csdnimg.cn/20190225032240703.jpg)\n",
    "\n",
    "- **切比雪夫距离**：可以称为l的范数距离，计算两点之间最大值\n",
    "\n",
    "- **余弦距离**：也称余弦相似度。实际上不是距离，是两个向量在方向上的相似度：\n",
    "  即两个向量的夹角的余弦值。如果两个向量夹角越接近0，则两个向量相似度越高。\n",
    "  如此，我们将向量空间中两个向量的夹角余弦值作为衡量两个数据间差异的度量。而余弦值越接近1，则认为相似度越高，余弦值越接近0，则认为相似度越低。\n",
    "  其距离是\n",
    "  ![在这里插入图片描述](https://img-blog.csdnimg.cn/20190225032228703.jpg)\n",
    "  即两个向量的乘积除以两个向量模的乘积。\n",
    "\n",
    "  2. ##### k值的选择：\n",
    "\n",
    "     通过上边的距离度量，我们假设某个特征空间中有两个集群，每个集群中有若干个元素。每个元素又是一个数据（比如矩阵或数组）。现在给出一个未知的待分类元素，首先我们将该元素每个集群中每个元素的距离求出，并将属于同一个类或群体的元素标记其组别，那么对于该空间中待分类元素与已有的每个元素的比较就得到与已有元素个数（假定为m）相匹配的m个数据di=[distance(new,already),group]。\n",
    "     现在对于已经得到的一个列表dist_list=[d1,d2,…,dm]，我们根据其所选择的距离对其进行排序。比如选择欧式距离，那么显然需要将距离越小的排在越前边，然后得到一个以距离distance为依据的排序过的列表或数组new_dist_list。那么接下来就是k值选择的问题了，因为我们不需要其对所有的数据求绝大多数所属类，因为我们无法确定已有的类别下数据量是否相等。因此我们需要对new_dist_list选择前k个元素。即k个距离最近邻的数据，到这一步，我们只需要判断这k个数据当中哪一个类别group所属的数据最多，那么就可以知道其所属类别了。如图所示：\n",
    "     ![img](https://img2018.cnblogs.com/blog/1664968/201906/1664968-20190612153834990-1991841164.png)\n",
    "     上文提到，我们无法确定已有的类别下数据量是否相等，因此k值的选择就成了一个问题。可以说，k值的选择对于模型的表现有着很大影响。\n",
    "     如果k值选择过小，那么其邻域过小，这种情况下“学习”的估计误差会增大。模型会变复杂，容易出现过拟合。可能会出现极端情况，比如周围刚好是几个噪声点，这样就会对结果造成很大影响。\n",
    "     同样的如果k值过大，模型会相对简单，容易出现欠拟合。比如如果一个特征空间中有两个集群A和B，如果A集群的元素量远大于B集群，而k值又过大，这种情况下对B集群是不公平的，判断结果也不公允。\n",
    "     因此在实际应用中，通常对于k我们选择一个较小的值，并会通过交叉验证等方法确定k的具体值。而一般情况下，k值的选择低于训练样本数的平方根。考虑到可能会出现1:1的情况，因此k值的选择尽量取奇数。\n",
    "\n",
    "  3. ##### 分类决策规则\n",
    "\n",
    "     KNN算法一般是用多数表决方法，即由输入实例的K个邻近的多数类决定输入实例的类。这种思想也是经验风险最小化的结果。\n",
    "\n",
    "     训练样本为(xi , yi)。当输入实例为 x，标记为c，![img](https://ask.hellobi.com/uploads/article/20190301/vomninedaj.webp)是输入实例x的k近邻训练样本集。\n",
    "\n",
    "     我们定义训练误差率是K近邻训练样本标记与输入标记不一致的比例，误差率表示为：\n",
    "\n",
    "     ![img](https://ask.hellobi.com/uploads/article/20190301/wonxuqakao.webp)\n",
    "\n",
    "     因此，要使误差率最小化即经验风险最小，就要使(2.1)式右端的![img](https://ask.hellobi.com/uploads/article/20190301/kaqnbkmjho.webp)最大，即K近邻的标记值尽可能的与输入标记一致，所以多数表决规则等价于经验风险最小化。   \n",
    "\n",
    "#### 三、KNN算法优缺点以及算法改进\n",
    "\n",
    "优缺点：\n",
    "\n",
    "1、简单，易于理解，是一个天然的多分类器；\n",
    "\n",
    "2、不需要庞大的样本数据也可以完成一个简单的分类；\n",
    "\n",
    "3、不需要训练和求解参数（既是优点也是缺点）；\n",
    "\n",
    "4、数据量大的时候，计算量也非常大（样本多，特征多）；\n",
    "\n",
    "5、不平衡样本处理能力差；\n",
    "\n",
    "6、并没有学习和优化的过程，严格来说不算是机器学习。\n",
    "\n",
    "改进：\n",
    "\n",
    "进行加权平均，离得近的样本给予更大的权重，离得远的样本使其权重变小。\n",
    "\n",
    "#### 四、KNN算法例题\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['k', 'k', 'k']\n",
      "k\n"
     ]
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAWoAAAD4CAYAAADFAawfAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjMsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+AADFEAAARNUlEQVR4nO3dYWgc553H8d9/beVajUbEOKIEu5wJuzgBw0VhyXF4CXeJWxI1hCM9mBRauLuA+6KUBB3U7b24cm/uTaDkXhWM7V6OpvG0cfKmLKEObekJ4hxr1xe7sc2qJaWO2lrhUrSevLCS/d+L3Vg5eWXtSju7z0rfDwjJM7szv0nYnx8986zX3F0AgHAVhh0AAHB7FDUABI6iBoDAUdQAEDiKGgACtzOPg951112+b9++PA4NAFvS2bNn33P3qU77cinqffv2qVar5XFoANiSzOy3a+1j6gMAAkdRA0DgKGoACBxFDQCBo6gBIHAUNQAELpfleQCw5TUaUppK9bpUKklJIsVxLqdat6jNbL+k9BOb7pH0L+7+fC6JACB0c3PSzIzUbEpZJkWRNDsrVatSpdL3061b1O5+RdL9kmRmOyS9K+nVvicBgFHQaLRKutFY2ZZlre8zM9LCgjQx0ddT9jpH/YikX7v7mu+gAYAtLU1bI+lOms3W/j7rtaifkvRSpx1mdtjMamZWW1xc3HwyAAhRvb4ygl4ty6T5+b6fsuuiNrM7JD0h6Ued9rv7UXcvu3t5aqrjvysCAKOvVGrNSXcSRVKx2PdT9jKifkzSOXf/Y99TAMCoSBKpsEZ1Fgqt/X3WS1F/SWtMewDAthHHrdUdcbwyso6ile19vpEodbmO2szGJX1O0lf7ngAARk2l0lrdkaatOelisTWSzqGkpS6L2t0/kLQ7lwQAMIomJqSnnx7IqXgLOQAEjqIGgMBR1AAQOIoaAAJHUQNA4ChqAAgcRQ0AgaOoASBwFDUABI6iBoDAUdQAEDiKGgACR1EDQOAoagAIHEUNAIGjqAEgcBQ1AASOogaAwFHUABA4ihoAAkdRA0DgKGoACBxFDQCB29nNg8zsTknHJB2Q5JL+0d3fyDMYgDU0GlKaSvW6VCpJSSLF8bBTIUddFbWkf5f0mrv/nZndIWk8x0wA1jI3J83MSM2mlGVSFEmzs1K1KlUqw06HnKxb1GY2KekhSX8vSe5+Q9KNfGMBuEWj0SrpRmNlW5a1vs/MSAsL0sTEcLIhV93MUd8jaVHS98zsl2Z2zMyinHMBWC1NWyPpTprN1n5sSd0U9U5JD0j6rrtPS8okfXP1g8zssJnVzKy2uLjY55gAVK+vjKBXyzJpfn6weTAw3RT1VUlX3f3N9p9fVqu4/x93P+ruZXcvT01N9TMjAKl14zBa45fZKJKKxcHmwcCsW9Tu/gdJvzOz/e1Nj0h6O9dUAG6VJFJhjZdsodDajy2p23XUX5f0opm9Jel+Sf+WXyQAHcVxa3VHHK+MrKNoZTs3Eresrpbnuft5SeWcswBYT6XSWt2Rpq056WKxNZKmpLe0btdRAwjFxIT09NPDToEB4i3kABA4ihoAAkdRA0DgKGoACBxFDQCBo6gBIHAUNQAEjqIGgMBR1AAQOIoaAAJHUQNA4ChqAAgcRQ0AgaOoASBwFDUABI6iBoDAUdQAEDiKGgACR1EDQOAoagAIHEUNAIGjqAEgcBQ1AARuZzcPMrN3JDUkfSTpQ3cv5xkKALCiq6Ju+xt3fy+3JACAjpj6AIDAdVvULuknZnbWzA53eoCZHTazmpnVFhcX+5cQALa5bov6oLs/IOkxSV8zs4dWP8Ddj7p72d3LU1NTfQ0JANtZV0Xt7gvt79ckvSrpwTxDAQBWrFvUZhaZWfzxz5I+L+li3sEAAC3drPr4jKRXzezjx//A3V/LNRUA4KZ1i9rdfyPpLwaQBQDQAcvzACBwFDUABI6iBoDAUdQAEDiKGgACR1EDQOAoagAIHEUNAIGjqAEgcBQ1AASOogaAwFHUABA4ihoAAkdRA0DgKGoACBxFDQCBo6gBIHAUNQAEjqIGgMBR1AAQuJEo6qWlJV29elVLS0vDjgIAAxdsUS8vL+vkyZOanp7W7t27tX//fu3evVvT09M6efKklpeXhx0RAAbC3L3vBy2Xy16r1Tb8/Pfff1+HDh3S5StX9EGW3bJ/PIp07/79ev3117Vr167NRAWAIJjZWXcvd9q3c9Bh1rO8vKxDhw7prQsX9OEao+YPskxvXbigQ4cO6cyZMxobGxtwyt40Gg2laap6va5SqaQkSRTH8bBjARgRXRe1me2QVJP0rrs/nlegU6dO6fLlK2uW9Mc+XF7W5ctX9MorryhJkrzibNrc3JxmZmbUbDaVZZmiKNLs7Kyq1aoqlcqw4wEYAV1PfZjZrKSypMn1inozUx/T09M6f/58T48/d+7chs6Vt0ajoT179qjRaNyyL45jLSwsaGJiYgjJAITmdlMfXd1MNLO9kr4g6Vg/g622tLSkixcv9vScixcvBrsaJE1TNZvNjvuazabSNB1wIgCjqNtVH89L+oakzq0jycwOm1nNzGqLi4sbCrO0tKQ77rijp+eMjY0FW9T1el1Zh5uhkpRlmebn5wecCMAoWreozexxSdfc/eztHufuR9297O7lqampDYWZnJzUjRs3enrO8vKyJicnN3S+vJVKJUVR1HFfFEUqFosDTgRgFHUzoj4o6Qkze0fSSUkPm9n38wgzOTmpAwcO9PScAwcOBFvUSZKoUOj8n7hQKAR9ExRAONYtanf/lrvvdfd9kp6S9FN3/3JegY4cOaLx8c6j0NXGxyMdOXIkryibFsexqtWq4ji+ObKOoujmdm4kAuhGcOuov/jFL+q555677TpqSdo5Nqb77rtXTz755ADT9a5SqWhhYUFpmmp+fl7FYlFJklDSALoW9jsTL1/RBx90eGfieKT77rtXp0+f5p2JALaETS/PG7Rdu3bpzJkzOnHiuKanpzU2Nqbx8XGNjY1penpaJ04c1xtvvEFJA9gWghxRr7a0tKSlpSVNTk4Ge+MQADZjpP6tj04oaADbWZBTHwCAFRQ1AASOogaAwFHUABA4ihoAAkdRA0DgKGoACBxFDQCBo6gBIHAUNQAEjqIGgMBR1AAQOIoaAAJHUQNA4ChqAAgcRQ0AgaOoASBwFDUABI6iBoDABf+ZiY1GQ2maql6vq1QqKUkSxXE87FgANqPRkNJUqtelUklKEonX9ZrW/RRyM/uUpF9I+jO1iv1ld//27Z7Tr08hn5ub08zMjJrNprIsUxRFKhQKqlarqlQqmz4+gCGYm5NmZqRmU8oyKYqkQkGqVqVt/Lq+3aeQd1PUJily9+tmNiZpTtIz7n5mref0o6gbjYb27NmjRqNxy744jrWwsKCJiYlNnQPAgDUa0p49re+rxbG0sCBt09f17Yp63Tlqb7ne/uNY++v27d4HaZqq2Wx23NdsNpWmad4RAPRbmrZG0p00m639uEVXNxPNbIeZnZd0TdJpd3+zw2MOm1nNzGqLi4ubDlav15VlWcd9WZZpfn5+0+cAMGD1emu6o5Msk3hdd9RVUbv7R+5+v6S9kh40swMdHnPU3cvuXp6amtp0sFKppCiKOu6LokjFYnHT5wAwYKVSa066kyiSeF131NPyPHf/k6SfS3o0lzSfkCSJCoXO8QqFgpIkyTsCgH5LktaNw04KhdZ+3GLdojazKTO7s/3zpyUdknQ572BxHKtarSqO45sj6yiKbm7nRiIwguK4tbojjldG1lG0sp3XdUfdrKO+W9ILZrZDrWL/obv/ON9YLZVKRQsLC0rTVPPz8yoWi0qShJIGRlml0lrdkaatOelisTWS5nW9pnWX521Ev9ZRA8B2sanleQCA4aKoASBwFDUABI6iBoDAUdQAEDiKGgACR1EDQOAoagAIHEUNAIGjqAEgcBQ1AASOogaAwFHUABA4ihoAAkdRA0DgKGoACBxFDQCBo6gBIHAUNQAEjqIGgMBR1AAQOIoaAAJHUQNA4ChqAAjcukVtZp81s5+Z2SUz+5WZPTOIYACAlp1dPOZDSf/k7ufMLJZ01sxOu/vbOWcDAKiLEbW7/97dz7V/bki6JGlP3sEAAC09zVGb2T5J05Le7LDvsJnVzKy2uLjYn3QAgO6L2swmJJ2S9Ky7L63e7+5H3b3s7uWpqal+ZgSAba2rojazMbVK+kV3fyXfSACAT+pm1YdJOi7pkrt/J/9IAIBP6mZEfVDSVyQ9bGbn218zOecCALStuzzP3eck2QCyAAA64J2JABA4ihoAAkdRA0DgKGoACBxFDQCBo6gBIHAUNQAEjqIGgMBR1AAQOIoaAAJHUQNA4ChqAAgcRQ0AgaOoASBwFDUABI6iBoDAUdQAEDiKGgACR1EDQOAoagAIHEUNAIGjqAEgcDuHHWA7aDQaStNU9XpdpVJJSZIojuNhxwIwItYtajM7IelxSdfc/UD+kbaWubk5zczMqNlsKssyRVGk2dlZVatVVSqVYccDMAK6mfr4D0mP5pxjS2o0GpqZmVGj0VCWZZKkLMtubr9+/fqQEwIYBesWtbv/QtL/DiDLlpOmqZrNZsd9zWZTaZoOOBGAUdS3m4lmdtjMamZWW1xc7NdhR1q9Xr85kl4tyzLNz88POBGAUdS3onb3o+5edvfy1NRUvw470kqlkqIo6rgviiIVi8UBJwIwiliel6MkSVQodP5PXCgUlCTJgBMBGEUUdY7iOFa1WlUcxzdH1lEU3dw+MTEx5IQARkE3y/NekvTXku4ys6uSvu3ux/MOtlVUKhUtLCwoTVPNz8+rWCwqSRJKGkDXzN37ftByuey1Wq3vxwWArcrMzrp7udM+pj4AIHAUNQAEjqIGgMBR1AAQOIoaAAKXy6oPM1uU9Ns+H/YuSe/1+ZiDxjWEYytcB9cQhn5dw5+7e8e3dedS1Hkws9paS1dGBdcQjq1wHVxDGAZxDUx9AEDgKGoACNwoFfXRYQfoA64hHFvhOriGMOR+DSMzRw0A29UojagBYFuiqAEgcMEXtZmdMLNrZnZx2Fk2ysw+a2Y/M7NLZvYrM3tm2Jl6ZWafMrP/NrP/aV/Dvw4700aZ2Q4z+6WZ/XjYWTbCzN4xswtmdt7MRvafqTSzO83sZTO73H5t/NWwM/XCzPa3/x98/LVkZs/mcq7Q56jN7CFJ1yX9p7sfGHaejTCzuyXd7e7nzCyWdFbS37r720OO1jUzM0mRu183szFJc5KecfczQ47WMzOblVSWNOnujw87T6/M7B1JZXcf6TeKmNkLkv7L3Y+Z2R2Sxt39T8POtRFmtkPSu5L+0t37/Wa/8EfUW+FT0N399+5+rv1zQ9IlSXuGm6o33nK9/cex9lfYf8t3YGZ7JX1B0rFhZ9nOzGxS0kOSjkuSu98Y1ZJue0TSr/MoaWkEinqrMbN9kqYlvTncJL1rTxmcl3RN0ml3H7lrkPS8pG9Iag47yCa4pJ+Y2VkzOzzsMBt0j6RFSd9rT0MdM7POnwQ9Gp6S9FJeB6eoB8jMJiSdkvSsuy8NO0+v3P0jd79f0l5JD5rZSE1Fmdnjkq65+9lhZ9mkg+7+gKTHJH2tPT04anZKekDSd919WlIm6ZvDjbQx7WmbJyT9KK9zUNQD0p7XPSXpRXd/Zdh5NqP9K+rPJT065Ci9OijpifYc70lJD5vZ94cbqXfuvtD+fk3Sq5IeHG6iDbkq6eonfit7Wa3iHkWPSTrn7n/M6wQU9QC0b8Qdl3TJ3b8z7DwbYWZTZnZn++dPSzok6fJwU/XG3b/l7nvdfZ9av6r+1N2/PORYPTGzqH1DWu2pgs9LGrkVUe7+B0m/M7P97U2PSBqZm+urfEk5TntIXXwK+bBtkU9BPyjpK5IutOd4Jemf3b06xEy9ulvSC+272wVJP3T3kVzeNuI+I+nV1t/92inpB+7+2nAjbdjXJb3Ynjr4jaR/GHKenpnZuKTPSfpqrucJfXkeAGx3TH0AQOAoagAIHEUNAIGjqAEgcBQ1AASOogaAwFHUABC4/wON+/SXmDZeYgAAAABJRU5ErkJggg==\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "#现在已有的一个数据集，其每一个数据是[打斗次数，接吻次数],我们用‘k’来表示爱情片，‘r’表示打斗片：\n",
    "#movie={‘k’:[[3,98],[12,103][1,81]],‘r’:[[101,10],[99,5],[98,2]]};\n",
    "#待分类元素为newmovie=[18,90]，现在对其进行测试分类\n",
    "\n",
    "import numpy as np;\n",
    "import matplotlib.pyplot as plot;\n",
    "\n",
    "def dist_e(A,B): #欧氏距离\n",
    "    A=np.array(A);\n",
    "    B=np.array(B);\n",
    "    a=A-B;\n",
    "    # print(np.matmul(a,a.T));\n",
    "    return np.linalg.norm(a);  #用于计算范数，默认情况为欧氏距离\n",
    "\n",
    "def dist_man(A,B): #曼哈顿距离\n",
    "    A=np.array(A);\n",
    "    B=np.array(B);\n",
    "    a=A-B;\n",
    "    a=np.abs(a);\n",
    "    a=a.ravel();  #矩阵降维\n",
    "    # print(np.matmul(a,a.T));\n",
    "    return sum(a);  \n",
    "\n",
    "def dist_cos(A,B): #余弦距离,结果越接近1，相似度越高，越接近0，相似度越低\n",
    "    A=np.array(A);\n",
    "    B=np.array(B);\n",
    "    d1=np.dot(A,B);\n",
    "    d2=np.linalg.norm(A)*np.linalg.norm(B);\n",
    "    return d1/d2;\n",
    "\n",
    "def knn_test(dataset,newfeature,k=3,distfun=dist_e,dist_reverse=False):  #极端情况\n",
    "    from collections import Counter;\n",
    "    distance=[];\n",
    "    for group in dataset:\n",
    "        for candidate in dataset[group]:\n",
    "            distance.append([distfun(newfeature,candidate),group]);\n",
    "    dp=lambda l:l[0];\n",
    "    distance=sorted(distance,key=dp,reverse=dist_reverse);\n",
    "    distance=[d[1] for d in distance][:k];\n",
    "    print(distance);\n",
    "    return Counter(distance).most_common(1)[0][0];\n",
    "    \n",
    "def knn_result_show(dataset,newfeature):\n",
    "    for i in dataset:\n",
    "        for j in dataset[i]:\n",
    "            plot.scatter(j[0],j[1],s=50,color=i);\n",
    "    plot.scatter(newfeature[0],newfeature[1],s=100);\n",
    "    result=knn_test(dataset,newfeature);\n",
    "    print(result);\n",
    "    plot.scatter(newfeature[0],newfeature[1],s=150,color=result);\n",
    "    plot.show();\n",
    "\n",
    "movie={'k':[[3,98],[12,103],[1,81]],'r':[[101,10],[99,5],[98,2]]};\n",
    "newmovie=[18,90];\n",
    "dataset={'k':[[1,3],[2,4],[2,1]],'r':[[6,3],[7,7],[5,6]]};\n",
    "newfeature=[1,4];\n",
    "knn_result_show(dataset,newfeature);"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
